﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections;
using csNotificaciones;

namespace MotorMetricas.Logica
{
    public class MetricaNumeroClases : AbstractMetrica
    {

        override public int Generar(String ruta) 
        {

            ManejoArchivo Manejador = new ManejoArchivo();
            ArrayList misarchivos = null;
            Boolean SinError = true;
            int NumeroClases = 0;

            if (Manejador.ValidarRuta(ruta))
            {
                /*
                 * el metodo ObtenerArchivos devuelve el Array de strings con las direcciones
                 * de todos los archivos a evaluar, recorriendo todas las subcarpetas
                 */
                misarchivos = Manejador.ObtenerArchivos(ruta);
            }
            else
            {
                SinError = false;
                //Console.WriteLine("ERROR: Ruta invalida");
            }

            if (SinError)
            {

                foreach (String rutaArchivo in misarchivos)
                {
                    int temp = 0;
                    if (Manejador.ValidarArchivo(rutaArchivo))
                    {
                        temp = ContarNumeroClases(rutaArchivo);
                        NumeroClases = NumeroClases + temp;
                    }
                }


            }
            Notificacion.mostrarVentana("Metrica de Numero de Clases", "La metrica se ha generado con éxito\nResultado: " + NumeroClases.ToString(), Notificacion.Imagen.Ok, 2);
            return NumeroClases;
        }


        static public int ContarNumeroClases(string rutaArchivo)
        {
            int numero = 0;
            string linea = null;
            string buscar = "class";
            string cmnt1 = "//";
            string cmnt2 = "/*";
            string cmnt3 = "*/";
            int indice = -2;
            int indiceCmnt1 = -2;
            int indiceCmnt2 = -2;
            int indiceCmnt3 = -2; 
            bool dentroCmnt = false;

            try
            {
                StreamReader archivo = new StreamReader(rutaArchivo);

                while ((linea = archivo.ReadLine()) != null)
                {

                    indice = linea.IndexOf(buscar);
                    indiceCmnt1 = linea.IndexOf(cmnt1);
                    indiceCmnt2 = linea.IndexOf(cmnt2);
                    indiceCmnt3 = linea.IndexOf(cmnt3);

                    //Si encuentra /* y no encuentra class registra inicio de comentario
                    if ((indiceCmnt2 >= 0) && (indice < 0))
                        dentroCmnt = true;


                    //Si encuentra */ y no encuentra class registra fin de comentario
                    if ((indiceCmnt3 >= 0) && (indice < 0))
                        dentroCmnt = false;


                    //Si se encuentra leyendo lineas dentro de comentarios no las procesa
                    if (!(dentroCmnt))
                    {
                        //Si encuentra indice para la palabra reservada 'class' es una posible linea a procesar
                        if (indice >= 0)
                        {
                            /*
                             * Si encuentra inicio de comentario doblebarra (//) 
                             * entra a preguntar si la declaracion de 'class' esta antes del comentario
                             */ 
                            if (indiceCmnt1 >= 0)
                            {
                                if (indiceCmnt1 > indice)
                                    numero++;
                            }
                            else
                            {
                                 // Verifica si encuentra declaracion de 'class' antes de / *  comentario   * / 
                                if (indiceCmnt2 >= 0)
                                {
                                    if (indiceCmnt2 > indice)
                                        numero++;
                                }
                                else
                                    numero++;
                            }

                        }
                    } // FIN    (!(dentroCmnt))

                    indiceCmnt1 = -2;
                    indiceCmnt2 = -2;
                    indiceCmnt3 = -2;
                    indice = -2;
                
                }

                archivo.Close();
            }
            catch (Exception)
            {
                Notificacion.mostrarVentana("Metrica de Numero de Clases", "Ha ocurrido un error al generar esta metrica", Notificacion.Imagen.Error, 1);
            }

            return numero;
        }

    }
}
